package com.cn.quartz;

//简单的任务管理类
//QuartzManager.java

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.quartz.CronTrigger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.SimpleTrigger;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/** */

/**
 * @author zlei
 * @version 1.00.000
 * @Title:Quartz管理类
 * @Description:
 * @Copyright:
 */
public class QuartzManage {
    /**
     * 调度器类工厂
     */
    private static SchedulerFactory sf = new StdSchedulerFactory();
    /**
     * 工作组默认名
     */
    private static String JOB_GROUP_NAME = "group1";
    /**
     * 触发器默认名
     */
    private static String TRIGGER_GROUP_NAME = "trigger1";
    /**
     * 打印日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(QuartzManage.class);
    /**
     * 调度器
     */
    private static Scheduler sched;

    /**
     * 取得指定格式的日期时间
     *
     * @param time
     * @return 指定格式的日期时间
     */
    public static Date convDate(String time) {

        SimpleDateFormat DateFormat = new SimpleDateFormat("yyyyMMddHHmmss");

        Date d = null;
        try {
            d = DateFormat.parse(time);
        } catch (ParseException e) {
            LOGGER.error(e.getMessage(), e);
        }
        if (LOGGER.isDebugEnabled()) {
            LOGGER.debug(d.toString());
        }
        return d;
    }

    /**
     * 获取调度器
     *
     * @return 调度器
     */
    public static Scheduler getScheduler() {
        if (sched == null) {
            System.out.println("sched is null");
            try {
                sched = sf.getScheduler();
            } catch (SchedulerException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
        try {
            if (!sched.isStarted()) {
                sched.start();
            }
        } catch (SchedulerException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return sched;
    }

    public QuartzManage() {

    }

    /** */
    /**
     * 添加一个定时任务，使用默认的任务组名，触发器名，触发器组名
     *
     * @param jobName 任务名
     * @param job     任务
     * @param time    时间设置，参考quartz说明文档
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void addJobForCronTrigger(String jobName, Job job, String time)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME,
                job.getClass());// 任务名，任务组，任务执行类
        // 触发器
        CronTrigger trigger = new CronTrigger(jobName, TRIGGER_GROUP_NAME);// 触发器名,触发器组
        trigger.setCronExpression(time);// 触发器时间设定
        sched.scheduleJob(jobDetail, trigger);

    }

    /** */
    /**
     * 添加一个定时任务，使用默认的任务组名，触发器名，触发器组名
     *
     * @param jobName            任务名
     * @param job                任务
     * @param time               时间设置，参考quartz说明文档
     * @param repeatIntervalTime 间隔时间 默认1000毫秒
     * @param repeatCount        重新执行次数 不同于执行次数，如果repeatCount=1,则实际执行次数为2，分别为原计划执行1次和重新执行1次
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void addJobForSimpleTrigger(String jobName, Job job,
                                              String time, long repeatIntervalTime, int repeatCount, String json,
                                              JobDataMap jdMap) throws SchedulerException, ParseException {
        sched = getScheduler();

        JobDetail jobDetail = new JobDetail(jobName, JOB_GROUP_NAME,
                job.getClass());// 任务名，任务组，任务执行类
        jobDetail.setRequestsRecovery(true);
        if (jdMap != null) {
            jobDetail.setJobDataMap(jdMap);
        }

        // new一个触发器
        SimpleTrigger simpleTrigger = new SimpleTrigger(jobName,
                TRIGGER_GROUP_NAME);
        // 设置作业启动时间

        simpleTrigger.setStartTime(convDate(time));
        // 设置作业执行间隔,以毫秒为单位
        if (repeatIntervalTime == 0) {
            repeatIntervalTime = 1000;
        }
        simpleTrigger.setRepeatInterval(repeatIntervalTime);
        // 设置作业执行次数
        simpleTrigger.setRepeatCount(repeatCount);
        // 设置作业执行优先级默认为5
        // simpleTrigger.setPriority(10);
        // 作业和触发器设置到调度器中
        try {
            sched.scheduleJob(jobDetail, simpleTrigger);
            // sched.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

    /** */
    /**
     * 添加一个定时任务
     *
     * @param jobName          任务名
     * @param jobGroupName     任务组名
     * @param triggerName      触发器名
     * @param triggerGroupName 触发器组名
     * @param job              任务
     * @param time             时间设置，参考quartz说明文档
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void addJobForCron(String jobName, String jobGroupName,
                                     String triggerName, String triggerGroupName, Job job, String time)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        JobDetail jobDetail = new JobDetail(jobName, jobGroupName,
                job.getClass());// 任务名，任务组，任务执行类
        // 触发器
        CronTrigger trigger = new CronTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
        trigger.setCronExpression(time);// 触发器时间设定
        sched.scheduleJob(jobDetail, trigger);
        // if (!sched.isShutdown())
        // sched.start();
    }

    /** */
    /**
     * 添加一个定时任务
     *
     * @param jobName            任务名
     * @param jobGroupName       任务组名
     * @param triggerName        触发器名
     * @param triggerGroupName   触发器组名
     * @param job                任务
     * @param time               时间设置，参考quartz说明文档
     * @param repeatIntervalTime 间隔时间 默认1000毫秒
     * @param repeatCount        重新执行次数 不同于执行次数，如果repeatCount=1,则实际执行次数为2，分别为原计划执行1次和重新执行1次
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void addJobForSimple(String jobName, String jobGroupName,
                                       String triggerName, String triggerGroupName, Job job, String time,
                                       long repeatIntervalTime, int repeatCount)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        JobDetail jobDetail = new JobDetail(jobName, jobGroupName,
                job.getClass());// 任务名，任务组，任务执行类

        // 触发器
        SimpleTrigger trigger = new SimpleTrigger(triggerName, triggerGroupName);// 触发器名,触发器组
        trigger.setStartTime(convDate(time));// 触发器时间设定
        if (repeatIntervalTime == 0) {
            repeatIntervalTime = 1000;
        }
        // 设置作业执行间隔,以毫秒为单位
        trigger.setRepeatInterval(repeatIntervalTime);

        // 设置作业执行次数
        trigger.setRepeatCount(repeatCount);
        sched.scheduleJob(jobDetail, trigger);
        // if (!sched.isShutdown())
        // sched.start();
    }

    /** */
    /**
     * 修改一个任务的触发时间(使用默认的任务组名，触发器名，触发器组名) * @param jobName 任务名
     *
     * @param time 时间设置，参考quartz说明文档
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void modifyJobTimeForCron(String jobName, String time)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);

        Trigger trigger = sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
        if (trigger != null) {
            CronTrigger ct = (CronTrigger) trigger;
            ct.setCronExpression(time);
            sched.rescheduleJob(ct.getName(), ct.getGroup(), ct);

        }

    }

    /** */
    /**
     * 修改一个任务的触发时间(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param jobName 任务名
     * @param time    时间设置，参考quartz说明文档
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void modifyJobTimeForSimple(String jobName, String time)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        Trigger trigger = sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
        if (trigger != null) {
            SimpleTrigger st = (SimpleTrigger) trigger;
            st.setStartTime(convDate(time));

            sched.rescheduleJob(st.getName(), st.getGroup(), st);

        }

    }

    /** */
    /**
     * 修改一个任务的触发时间
     *
     * @param triggerName      触发器名称
     * @param triggerGroupName 触发器组名称
     * @param time             触发时间
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void modifyJobTimeForCron(String triggerName,
                                            String triggerGroupName, String time) throws SchedulerException,
            ParseException {
        sched = getScheduler();
        Trigger trigger = sched.getTrigger(triggerName, triggerGroupName);
        if (trigger != null) {
            CronTrigger ct = (CronTrigger) trigger;
            // 修改时间
            ct.setCronExpression(time);
            // 重启触发器
            sched.rescheduleJob(ct.getName(), ct.getGroup(), ct);
        }
    }

    /** */
    /**
     * 修改一个任务的触发时间
     *
     * @param triggerName      触发器名称
     * @param triggerGroupName 触发器组名称
     * @param time             触发时间
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void modifyJobTimeForSimple(String triggerName,
                                              String triggerGroupName, String time) throws SchedulerException,
            ParseException {
        sched = getScheduler();
        Trigger trigger = sched.getTrigger(triggerName, triggerGroupName);
        if (trigger != null) {
            SimpleTrigger st = (SimpleTrigger) trigger;
            // 修改时间
            st.setStartTime(convDate(time));
            // 重启触发器
            sched.rescheduleJob(st.getName(), st.getGroup(), st);
        }
    }

    /** */
    /**
     * 修改一个任务的短信发送内容(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param jobName 任务名
     * @param time    发送时间
     * @throws SchedulerException
     * @throws ParseException
     */
    public static void modifyJobJsonForSimple(String jobName, String json)
            throws SchedulerException, ParseException {
        sched = getScheduler();
        JobDetail jobDetail = sched.getJobDetail(jobName, JOB_GROUP_NAME);
        JobDataMap map = jobDetail.getJobDataMap();
        if (json == null) {
            json = "";
        }
        map.put("jsonStr", json);
        Trigger trigger = sched.getTrigger(jobName, TRIGGER_GROUP_NAME);
        if (trigger != null) {
            SimpleTrigger st = (SimpleTrigger) trigger;
            st.setJobDataMap(map);
            sched.rescheduleJob(st.getName(), st.getGroup(), st);
        }
        System.out.println(sched.getJobDetail(jobName, JOB_GROUP_NAME)
                .getJobDataMap().get("jsonStr"));
    }

    /** */
    /**
     * 移除一个任务(使用默认的任务组名，触发器名，触发器组名)
     *
     * @param jobName 任务名
     * @throws SchedulerException
     */
    public static void removeJob(String jobName) throws SchedulerException {
        sched = getScheduler();
        sched.pauseTrigger(jobName, TRIGGER_GROUP_NAME);// 停止触发器
        sched.unscheduleJob(jobName, TRIGGER_GROUP_NAME);// 移除触发器
        sched.deleteJob(jobName, JOB_GROUP_NAME);// 删除任务
    }

    /** */
    /**
     * 移除一个任务
     *
     * @param jobName          任务名称
     * @param jobGroupName     任务组名称
     * @param triggerName      触发器名称
     * @param triggerGroupName 触发器组名称
     * @throws SchedulerException
     */
    public static void removeJob(String jobName, String jobGroupName,
                                 String triggerName, String triggerGroupName)
            throws SchedulerException {
        sched = getScheduler();
        sched.pauseTrigger(triggerName, triggerGroupName);// 停止触发器
        sched.unscheduleJob(triggerName, triggerGroupName);// 移除触发器
        sched.deleteJob(jobName, jobGroupName);// 删除任务
    }

    /** */
    /**
     * 测试方法
     *
     * @param args
     */
    public static void main(String[] args) {
        SimpleDateFormat DateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date d = new Date();
        String returnstr = DateFormat.format(d);

        SMSSendJob job = new SMSSendJob();

        String job_name = "12";
        try {
            System.out.println(returnstr + "【系统启动】");
            QuartzManage.addJobForSimpleTrigger(job_name, job, returnstr, 0, 0,
                    "jsonStr", null); // 每2秒钟执行一次

            // 测试调度器唯一
            // Thread.sleep(30000);
            // Date d1 = new Date();
            // String returnstr1 = DateFormat.format(d1);
            // System.out.println(returnstr + "【系统启动】");
            // QuartzManage.addJobForSimpleTrigger(job_name, job, returnstr1);
            // // 每2秒钟执行一次

            // Thread.sleep(10000);

            // System.out.println("【修改时间】");
            // QuartzManage.modifyJobTime(job_name,"0/3 * * * * ?");
            // Thread.sleep(10000);
            // System.out.println("【移除定时】");
            // QuartzManage.removeJob(job_name);
            // Thread.sleep(10000);
            //
            // System.out.println("/n【添加定时任务】");
            // QuartzManage.addJob(job_name,job,"0/5 * * * * ?");

        } catch (Exception e) {
            LOGGER.error(e.getMessage(), e);
        }
    }

}
